#ifndef __M_CONNECTION_H__
#define __M_CONNECTION_H__
#include"mq_channel.hpp"

namespace bitmq{
    class Connection{
        public:
        using ptr=std::shared_ptr<Connection>;
        Connection(const muduo::net::TcpConnectionPtr&connection,
            const ProtobufCodecPtr&codec,
            const VirtualHost::ptr&vhost,
            const threadpool::ptr&pool,
            const ConsumerManager::ptr& cmp)
            :_connection(connection)
            ,_codec(codec)
            ,_vhost(vhost)
            ,_pool(pool)
            ,_cmp(cmp)
            ,_channels(std::make_shared<ChannelManager>()){}
        //打开信道
        void openChannel(const bitmq::openChannelRequestPtr&req)
        {
            bool ret=_channels->openChannel(req->cid(),_connection,_codec,_vhost,_pool,_cmp);
            if(ret==false)//有重复信道，打开失败
            {
                return basicResponse(false,req->rid(),req->cid());
            }
            return basicResponse(true,req->rid(),req->cid());

        }
        void closeChannel(const closeChannelRequestPtr&req)
        {
            _channels->closeChannel(req->cid());
            return basicResponse(true,req->rid(),req->cid());
                
        }
        
        Channel::ptr getChannel(const std::string&cid)
        {
            return _channels->getChannel(cid);
        }
        private:
        void basicResponse(bool ok,const std::string&rid,const std::string&cid)
        {
            basicCommonRespose rep;
            rep.set_ok(ok);
            rep.set_rid(rid);
            rep.set_cid(cid);
             _codec->send(_connection,rep);
        }
        muduo::net::TcpConnectionPtr _connection;//连接管理句柄
        ProtobufCodecPtr _codec;//协议处理句柄
        VirtualHost::ptr _vhost;//虚拟机管理句柄
        threadpool::ptr _pool;
        ConsumerManager::ptr _cmp;//消费者管理句柄
        ChannelManager::ptr _channels;
    };
    class ConnectionManager
    {
        public:
        using ptr=std::shared_ptr<ConnectionManager>;
        ConnectionManager(){}
        void newConnection(const muduo::net::TcpConnectionPtr&connection,
            const ProtobufCodecPtr&codec,
            const VirtualHost::ptr&vhost,
            const threadpool::ptr&pool,
            const ConsumerManager::ptr& cmp)
            {
                std::unique_lock<std::mutex> lock(_mutex);
                auto it=_conns.find(connection);
                if(it!=_conns.end())
                {
                    DLOG("有重复连接");
                    return;
                }

                auto self_con=std::make_shared<Connection>(connection,codec,vhost,pool,cmp);
                _conns.insert(std::make_pair(connection,self_con));
            }
        void deleteConnection(const muduo::net::TcpConnectionPtr&connection){
            std::unique_lock<std::mutex> lock(_mutex);
            _conns.erase(connection);
        }
        Connection::ptr getConnection(const muduo::net::TcpConnectionPtr&connection){
            std::unique_lock<std::mutex> lock(_mutex);
            auto it=_conns.find(connection);
            if(it==_conns.end())
            {
                DLOG("没找到连接");
                return Connection::ptr();
            }
            return it->second;
        }
      
        private:
        std::mutex _mutex;
        std::unordered_map<muduo::net::TcpConnectionPtr,Connection::ptr> _conns;
    };
}

#endif